home *** CD-ROM | disk | FTP | other *** search
/ NeXT Education Software Sampler 1992 Fall / NeXT Education Software Sampler 1992 Fall.iso / Programming / Source / Unknown / Unknown.m < prev    next >
Encoding:
Text File  |  1991-04-02  |  4.5 KB  |  187 lines

  1. /* File: Unknown.m - The 'Unknown' Application
  2.  *
  3.  * By: Christopher Lane
  4.  * Symbolic Systems Resources Group
  5.  * Knowledge Systems Laboratory
  6.  * Stanford University
  7.  *    
  8.  * Contributor(s):
  9.  *    
  10.  *     Jiro Nakamura (jiro@heights.cit.cornell.edu)
  11.  *
  12.  * Date: 2 April 1991
  13.  *
  14.  * Copyright: 1989, 1990 & 1991 by The Leland Stanford Junior University.
  15.  * This program may be distributed without restriction for non-commercial use.
  16.  */
  17.  
  18. #import "Unknown.h"
  19.  
  20. #import <c.h>
  21. #import <libc.h>
  22. #import <stdlib.h>
  23. #import <ldsyms.h>
  24. #import <strings.h>
  25.  
  26. #import <sys/file.h>
  27. #import <sys/loader.h>
  28.  
  29. #import <objc/typedstream.h>
  30. #import <objc/HashTable.h>
  31.  
  32. #import <appkit/Panel.h>
  33. #import <appkit/Speaker.h>
  34. #import <appkit/Listener.h>
  35. #import <appkit/defaults.h>
  36.  
  37. // #import <text/pathutil.h>
  38.  
  39. #define APPLICATION "Unknown"
  40.  
  41. #define VERIFYDEFAULTSTRING "Verify"
  42. #define DEFAULTVERIFYSTRING "Yes"
  43. #define REPORTERRORDEFAULTSTRING "ReportError"
  44. #define DEFAULTREPORTERRORSTRING "Yes"
  45.  
  46. #define getDefaultValue(s) NXGetDefaultValue(APPLICATION, s)
  47. #define registerDefaults(s) NXRegisterDefaults(APPLICATION, s)
  48.  
  49. #define getDefaultBoolValue(s) (BOOL) (strncmp(getDefaultValue(s), "Yes", 1) == EQ)
  50.  
  51. static NXDefaultsVector UnknownDefaults = {
  52.     { VERIFYDEFAULTSTRING, DEFAULTVERIFYSTRING },
  53.     { REPORTERRORDEFAULTSTRING, DEFAULTREPORTERRORSTRING },
  54.     { NULL }
  55.     };
  56.  
  57. #define HASHSEGMENT "__HASHTABLE"
  58. #define HASHSECTION "__DATA"
  59.  
  60. #define ICONSEGMENT "__ICON"
  61. #define ICONSECTION "__header"
  62.  
  63. #define BUFFERSIZE 1024
  64. #define BITSPERBYTE 8
  65.  
  66. #define EXECUTESTRING "Execute?"
  67. #define ERRORSTRING "Error running '%s', exit code = %d."
  68.  
  69. #define DEFAULTBUTTON "OK"
  70. #define ALTERNATEBUTTON "Cancel"
  71.  
  72. typedef enum { LT = -1, EQ, GT } COMPARISON;
  73.  
  74. char *basename(char *path)
  75.     char *s;
  76.     
  77.     if((s = rindex(path, '/')) != NULL) return ++s;
  78.     
  79.     return path;
  80. }
  81.  
  82. char *parentname(char *path)
  83.     char *p, *s = NXCopyStringBuffer(path);
  84.     
  85.     if((p = rindex(s, '/')) == NULL) { p = s; *p++ = '.'; }
  86.         
  87.     *p = '\0';
  88.     
  89.     return s;
  90. }
  91.  
  92. @implementation Unknown : Application
  93.  
  94. + new
  95. {
  96.     self = [super new];
  97.     
  98.     (void) registerDefaults(UnknownDefaults);
  99.     
  100.     return self;
  101. }
  102.  
  103. - (BOOL) appAcceptsAnotherFile:sender { return(YES); };
  104.  
  105. - (int) appOpenFile:(const char *) filename type:(const char *) aType
  106. {
  107.     int status;
  108.     char buffer[BUFFERSIZE];
  109.     const char *program, *base = basename((char *) filename);
  110.     HashTable *table = [self loadSegment:HASHSEGMENT section:HASHSECTION];
  111.  
  112.     if(access(filename, R_OK) == CERROR) return (int) [self unix_error:"access"];
  113.     if(chdir(parentname((char *) filename)) == CERROR) return (int) [self unix_error:"chdir"];
  114.         
  115.     if((program = [table valueForKey:aType]) != NULL) {
  116.         (void) sprintf(buffer, program, base, base, base, base, base);
  117.         if(! getDefaultBoolValue(VERIFYDEFAULTSTRING) ||
  118.           (NXRunAlertPanel(EXECUTESTRING, buffer, DEFAULTBUTTON, ALTERNATEBUTTON, NULL) == NX_OKTAG)) {
  119.               if((status = system(buffer)) == CERROR) return (int) [self unix_error:"system"];
  120.             status >>= BITSPERBYTE;
  121.             if(status != EXIT_SUCCESS && getDefaultBoolValue(REPORTERRORDEFAULTSTRING))
  122.                 NXRunAlertPanel(NULL, ERRORSTRING, NULL, NULL, NULL, buffer, status);
  123.             }
  124.         }
  125.     else return [self ReOpenFile:filename type:aType];
  126.  
  127.     return(YES);
  128. }
  129.  
  130. - appDidInit:sender { return [self terminate:sender]; }
  131.  
  132. - loadSegment:(const char *) segment section:(const char *) section
  133. {
  134.     int size;
  135.     id object;
  136.     void *pointer;
  137.     NXStream *stream;
  138.     NXTypedStream *typedstream;
  139.     
  140.     pointer = getsectdata(segment, section, &size);
  141.     stream = NXOpenMemory((const char *) pointer, size, NX_READONLY);
  142.     typedstream = NXOpenTypedStream(stream, NX_READONLY);
  143.     object = NXReadObject(typedstream);
  144.     NXCloseTypedStream(typedstream);
  145.  
  146.     return object;
  147. }
  148.  
  149. - (int) ReOpenFile:(const char *) filename type:(const char *) aType
  150. {
  151.     int size, result;
  152.     void *pointer;
  153.     port_t port;
  154.     id speaker = [NXApp appSpeaker];
  155.     NXStream *stream;
  156.     char application[BUFFERSIZE], extension[BUFFERSIZE];
  157.     
  158.     pointer = getsectdata(ICONSEGMENT, ICONSECTION, &size);
  159.     stream = NXOpenMemory((const char *) pointer, size, NX_READONLY);
  160.     
  161.     while(NXScanf(stream, "%*s %*s %s %s", application, extension) != EOF && strcmp(extension, aType) != 0);
  162.     
  163.     NXCloseMemory(stream, NX_FREEBUFFER);
  164.  
  165.     if(strcmp(application, [self appName]) == 0) return(YES);
  166.     
  167.     if((port = NXPortFromName(application, NULL)) == PORT_NULL)
  168.         return (int) [self unix_error:"NXPortFromName"];
  169.  
  170.     [speaker setSendPort:port];
  171.     
  172.     if([speaker openFile:filename ok:&result] != SEND_SUCCESS)
  173.         return (int) [self unix_error:"openFile:ok:"];
  174.  
  175.     return(YES);
  176. }
  177.  
  178. - (BOOL) unix_error:(const char *) string
  179. {
  180.     perror(string);
  181.     return(NO);
  182. }
  183.  
  184. @end
  185.